/**
 * 导入模块
 */
import axios from 'axios';

/**
 * 导入类型声明
 */
import type { AxiosInstance, AxiosResponse } from 'axios';
import type { InterceptorHooks, ExpandAxiosRequestConfig } from './types';

/**
 * 定义请求类
 */
class AxiosRequest {
  /**
   * axios 实例
   */
  private _instance: AxiosInstance;

  /**
   * 自定义拦截器
   */
  private _interceptorHooks?: InterceptorHooks;

  /**
   * 构造函数，用于创建 AxiosRequest 实例
   * @param config - 扩展的 Axios 请求配置对象
   */
  constructor(config: ExpandAxiosRequestConfig) {
    // 使用传入的配置对象创建一个新的 Axios 实例
    this._instance = axios.create(config);
    // 设置默认的请求头 Content-Type 为 application/json;charset=utf-8
    this._instance.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';
    // 从配置对象中提取自定义拦截器钩子
    this._interceptorHooks = config.interceptorHooks;
    // 调用 setupInterceptors 方法来设置自定义拦截器
    this.setupInterceptors();
  }

  /**
   * 设置拦截器
   * 该方法用于为Axios实例添加请求和响应拦截器。
   * 请求拦截器在请求发送前执行，可以用于修改请求配置或添加请求头等操作。
   * 响应拦截器在接收到响应后执行，可以用于处理响应数据或处理错误等操作。
   */
  private setupInterceptors() {
    // 添加请求拦截器
    this._instance.interceptors.request.use(
      // 使用自定义的请求拦截器，如果没有定义则使用默认的
      this._interceptorHooks?.requestInterceptor,
      // 使用自定义的请求拦截器错误处理函数，如果没有定义则使用默认的
      this._interceptorHooks?.requestInterceptorCatch,
    );
    // 添加响应拦截器
    this._instance.interceptors.response.use(
      // 使用自定义的响应拦截器，如果没有定义则使用默认的
      this._interceptorHooks?.responseInterceptor,
      // 使用自定义的响应拦截器错误处理函数，如果没有定义则使用默认的
      this._interceptorHooks?.responseInterceptorCatch,
    );
  }

  /**
   * 基础get方法
   * @param url
   * @param config
   * @returns
   */
  public get<T = any>(url: string, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.get(url, config);
  }

  /**
   * 基础post方法
   * @param url
   * @param data
   * @param config
   * @returns
   */
  public post<T = any>(url: string, data?: any, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.post(url, data, config);
  }

  /**
   * 基础put方法
   * @param url
   * @param data
   * @param config
   * @returns
   */
  public put<T = any>(url: string, data?: any, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.put(url, data, config);
  }

  /**
   * 基础删除方法
   * @param url
   * @param config
   * @returns
   */
  public delete<T = any>(url: string, config?: ExpandAxiosRequestConfig): Promise<T> {
    return this._instance.delete(url, config);
  }

  /**
   * 基础通用方法，传入config,自由配置组合
   * @param config
   * @returns
   */
  public request<T = any>(config: any): Promise<T> {
    return this._instance.request(config);
  }
}

export default AxiosRequest;
